Made a couple of cotoGPS fixes to get this format back
authoroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sat, 22 Oct 2005 19:45:11 +0000 (19:45 +0000)
committeroliskoli <oliskoli@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sat, 22 Oct 2005 19:45:11 +0000 (19:45 +0000)
gpsbabel/README
gpsbabel/coto.c
gpsbabel/reference/cototestmarker.gpx
gpsbabel/testo
gpsbabel/vecs.c

index 17493f49ecdb67d30e9cbe90876ff269ff6023a0..02d8d35220211a1cb4577a8dfc52e4de51a02a0f 100644 (file)
@@ -1084,6 +1084,7 @@ THE FORMATS
                 -F a_to_b.bcr
        
     OPENOFFICE
+    
        Tab seperated export-all (except geocaching data) file format. 
        Intended to serve as source for number-processing applications
        like OpenOffice, Ploticus and others. Tab was chosen as delimiter
@@ -1092,6 +1093,27 @@ THE FORMATS
        it to locales where ',' is used as decimal seperator.
        Contributed by Tobias Minich.
        
+    COTO
+    
+        Format for cotoGPS, a Palm GPS program. It can read both 
+       track and marker (waypoint) files. It is currently unable
+       to write track files, so only marker files can be written. The 
+       marker categories are written to and read from the icon 
+       description. The 'Not Assigned' category leaves the icon 
+       description empty on read. Currently geocache info is ignored.
+       
+       Options:
+       
+           zerocat (output) - Name for the Palm 'Not Assigned' category.
+               Defaults to 'Not Assigned'.
+           There is also a debugging option called 'internals' which 
+               takes a XCSV delimiter value. It writes some internal 
+               values (distance, arc, x and y) of the cotoGPS track 
+               format to the notes field.
+              
+       URL: http://core.de/~coto/projects/cotogps/
+       Contributed by Tobias Minich.
+       
     GEOnet
     
        Input support for the GEOnet Names Server (GNS) country file 
index 1ccb4673be91b5d2947bc9d4ec792f3bad131e58..d3d363b082ca512a756c5b16922f31d4bcaf9b58 100644 (file)
@@ -1,7 +1,7 @@
 /*
-    Read and write Coto files.
+    Read and write cotoGPS files.
 
-    Copyright (C) 2005 Tobias Minich, robertlipe@usa.net
+    Copyright (C) 2005 Tobias Minich,
     
     Based on the Cetus I/O Filter,
     Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
 #include "coldsync/pdb.h"
 
 #define MYNAME "cotoGPS"
+
 #define MYTYPETRACK    0x5452434b      /* TRCK */
 #define MYTYPEWPT      0x44415441      /* DATA */
-#define MYCREATOR              0x636f4750      /* coGP */
+#define MYCREATOR      0x636f4750      /* coGP */
 
 #define NOTESZ 4096
 #define DESCSZ 4096
 
+#define MAX_MARKER_NAME_LENGTH 20
+#define CATEGORY_NAME_LENGTH 16
+
 typedef enum {
-       cotofixNone = 0,                /* No Fix or Warning */
+       cotofixNone = 0,        /* No Fix or Warning */
        cotofixReserved = 1,    /* Shouldn't occur*/
-       cotofix2D = 2,                  /* retrieved from a GPS with a 2D fix */
-       cotofix3D = 3,                  /* retrieved from a GPS with a 3D fix  */
-       cotofixDGPS = 4,                /* retrieved from a GPS with a DGPS signal */
+       cotofix2D = 2,          /* retrieved from a GPS with a 2D fix */
+       cotofix3D = 3,          /* retrieved from a GPS with a 3D fix  */
+       cotofixDGPS = 4,        /* retrieved from a GPS with a DGPS signal */
 } fix_quality;
 
 struct record_track {
@@ -54,21 +58,21 @@ struct record_track {
        word alt;               /* Altitude */
 
        /* accuracy and precision information for use where applicable */
-       uword hdop; /* _dop * 10 */
-       uword vdop;
-       uword pdop;
+       gbuint16 hdop; /* _dop * 10 */
+       gbuint16 vdop;
+       gbuint16 pdop;
        ubyte sat_tracked;
        ubyte fix_quality;
 
-       uword speed; /* *10 */
-       udword time; /* Palm Time */
+       gbuint16 speed; /* *10 */
+       gbuint32 time; /* Palm Time */
 };
 
-#define MAX_MARKER_NAME_LENGTH 20
 struct record_wpt {
      char lon[8];
      char lat[8];
      char name[MAX_MARKER_NAME_LENGTH];
+     char notes[1];
 };
 
 
@@ -76,29 +80,30 @@ struct record_wpt {
 
 typedef char appinfo_category[16];
 
-#define APPINFO_PACKED_SIZE sizeof(uword)+16*sizeof(appinfo_category)+17*sizeof(ubyte)
-struct appinfo {
-       uword renamedCategories;
-       appinfo_category categories[16];
+typedef struct appinfo {
+       ubyte U0;
+       ubyte renamedCategories;
+       appinfo_category categories[CATEGORY_NAME_LENGTH];
        ubyte ids[16];
        ubyte maxid;
-};
+} appinfo_t;
+
+#define APPINFO_SIZE sizeof(appinfo_t)
 
 static FILE *file_in;
 static FILE *file_out;
 static const char *out_fname;
 static const char *in_fname; /* We might need that for naming tracks */
 static struct pdb *opdb;
+static short_handle  mkshort_wr_handle;
 
-static char *trackname = NULL;
 static char *zerocat = NULL;
 static char *internals = NULL;
 
 static
 arglist_t coto_args[] = {
-       {"trackname", &trackname, "Track name", NULL, ARGTYPE_STRING },
        {"zerocat", &zerocat, "Name of the 'unassigned' category.", NULL, ARGTYPE_STRING },
-       {"internals", &internals, "Export some internal stuff to notes.", NULL, ARGTYPE_STRING|ARGTYPE_HIDDEN },
+       {"internals", &internals, "Export some internal stuff to notes.", NULL, ARGTYPE_STRING | ARGTYPE_HIDDEN },
        {0, 0, 0, 0, 0 }
 };
 
@@ -113,10 +118,6 @@ static void
 rd_deinit(void)
 {
        fclose(file_in);
-       if ( trackname ) {
-           xfree(trackname);
-           trackname = NULL;
-       }
 }
 
 static void
@@ -130,10 +131,24 @@ static void
 wr_deinit(void)
 {
        fclose(file_out);
-       if ( trackname ) {
-           xfree(trackname);
-           trackname = NULL;
+}
+
+/* helpers */
+
+static char *
+coto_get_icon_descr(int category, const appinfo_t *app)
+{
+       char buff[CATEGORY_NAME_LENGTH + 1] = "Not Assigned";
+       if ((category >= 0) && (category < 16))
+       {
+               if ((category > 0) && (app->categories[category][0] == '\0'))
+                       category = 0;
+                       
+               strncpy(buff, app->categories[category], sizeof(buff) - 1);
+               if (buff[0] == '\0')
+                       return NULL;
        }
+       return xstrdup(buff);
 }
 
 static void
@@ -142,43 +157,48 @@ coto_track_read(struct pdb *pdb)
        struct record_track *rec;
        struct pdb_record *pdb_rec;
        route_head *trk_head;
-       char *loctrackname = NULL;
+       char *track_name;
        
-       if (trackname)
-               // Given by user
-               loctrackname = xstrdup(trackname);
-       else if (strncmp(pdb->name, "cotoGPS TrackDB", PDB_DBNAMELEN))
+       if (strncmp(pdb->name, "cotoGPS TrackDB", PDB_DBNAMELEN) != 0)
                // Use database name if not default
-               loctrackname = xstrndup(pdb->name, PDB_DBNAMELEN);
+               track_name = xstrndup(pdb->name, PDB_DBNAMELEN);
        else {
-               // Use filename
-               const char *fnametmp = strrchr(in_fname, '/'); // FIXME: Don't know if this works on Windows
+               // Use filename for new track title
+               const char *fnametmp = strrchr(in_fname, '/');
+               if (fnametmp == NULL)
+                       fnametmp = strrchr(in_fname, '\\');
                if (fnametmp)
                        fnametmp++;
                else
                        fnametmp = in_fname;
-               loctrackname = xstrndup(fnametmp, strrchr(fnametmp,'.')-fnametmp);
+               if (strrchr(fnametmp, '.') != NULL)
+                       track_name = xstrndup(fnametmp, strrchr(fnametmp,'.') - fnametmp);
+               else
+                       track_name = xstrdup(fnametmp);
        }
        
        trk_head = route_head_alloc();
        track_add_head(trk_head);
                
-       trk_head->rte_name = loctrackname;
+       trk_head->rte_name = track_name;
        
-       for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) {
+       for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next)
+       {
                waypoint *wpt_tmp;
 
                wpt_tmp = waypt_new();
 
                rec = (struct record_track *) pdb_rec->data;
-
+               
                wpt_tmp->longitude = -pdb_read_double(&rec->longitude)*360.0/(2.0*M_PI); 
                wpt_tmp->latitude = pdb_read_double(&rec->latitude)*360.0/(2.0*M_PI);
+
                // It's not the course, so leave it out for now
                // wpt_tmp->course = pdb_read_double(&rec->arc);
                wpt_tmp->altitude = be_read16(&rec->alt);
                
-               if (internals) {
+               if (internals)
+               {
                        // Parse the option as xcsv delimiter
                        const char *inter = xcsv_get_char_from_constant_table(internals);
                        char temp[256];
@@ -191,20 +211,33 @@ coto_track_read(struct pdb *pdb)
                wpt_tmp->hdop = be_read16(&rec->hdop)/10.0;
                wpt_tmp->vdop = be_read16(&rec->vdop)/10.0;
                wpt_tmp->sat = rec->sat_tracked;
-               switch (rec->fix_quality) {
-                       case cotofixNone:  wpt_tmp->fix = fix_none; break;
-                       case cotofixReserved:  wpt_tmp->fix = fix_unknown; break;
-                       case cotofix2D: wpt_tmp->fix = fix_2d; break;
-                       case cotofix3D: wpt_tmp->fix = fix_3d; break;
-                       case cotofixDGPS: wpt_tmp->fix = fix_dgps; break;
+               switch (rec->fix_quality)
+               {
+                       case cotofixNone:
+                               wpt_tmp->fix = fix_none; 
+                               break;
+                       case cotofixReserved:  
+                               wpt_tmp->fix = fix_unknown; 
+                               break;
+                       case cotofix2D: 
+                               wpt_tmp->fix = fix_2d; 
+                               break;
+                       case cotofix3D: 
+                               wpt_tmp->fix = fix_3d; 
+                               break;
+                       case cotofixDGPS: 
+                               wpt_tmp->fix = fix_dgps; 
+                               break;
                }
                wpt_tmp->speed = be_read16(&rec->speed)/10.0;
-               wpt_tmp->creation_time = be_read32(&rec->time) - 2082844800U;
-
+               rec->time = be_read32(&rec->time);
+               if (rec->time != 0)
+               {
+                       rec->time -= 2082844800U;
+                       wpt_tmp->creation_time = rec->time;
+               }
                route_add_wpt(trk_head, wpt_tmp);
-
        } 
-       
 }
 
 static void
@@ -212,43 +245,27 @@ coto_wpt_read(struct pdb *pdb)
 {
        struct record_wpt *rec;
        struct pdb_record *pdb_rec;
-       char *vdata;
-       struct appinfo *app;
-               
+       appinfo_t *app;
        app = (struct appinfo *) pdb->appinfo;
        
-       for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next) {
+       for(pdb_rec = pdb->rec_index.rec; pdb_rec; pdb_rec=pdb_rec->next)
+       {
                waypoint *wpt_tmp;
-               int c=-1;
                
                wpt_tmp = waypt_new();
 
                rec = (struct record_wpt *) pdb_rec->data;
                        
-               // Find category
-               /* I thought this would be the proper way. Leaving it in in case it becomes the proper one =)
-               for(i=0;i<16;i++)
-                       if (app->ids[i] == pdb_rec->category) {c=i; break;}
-               */
-               c = pdb_rec->category;
-               
                wpt_tmp->longitude = -pdb_read_double(&rec->lon)*360.0/(2.0*M_PI); 
                wpt_tmp->latitude = pdb_read_double(&rec->lat)*360.0/(2.0*M_PI);
                
-               wpt_tmp->shortname = xstrdup((char *) &rec->name);
-               wpt_tmp->description = xstrdup((char *) &rec->name);
-                       
-               if (c>0)
-                       wpt_tmp->icon_descr = xstrndup(app->categories[c], 16);
-               else if (c<0) 
-                       wpt_tmp->icon_descr = xstrdup("Unknown");
+               wpt_tmp->shortname = xstrndup(rec->name, sizeof(rec->name));
+               
+               wpt_tmp->icon_descr = coto_get_icon_descr(pdb_rec->category, app);
                if (wpt_tmp->icon_descr)
                        wpt_tmp->wpt_flags.icon_descr_is_dynamic = 1; 
                
-               if (pdb_rec->data_len>sizeof(*rec)) {
-                       vdata = (char *) pdb_rec->data + sizeof(*rec);
-                       wpt_tmp->notes = xstrdup(vdata);
-               }
+               wpt_tmp->notes = xstrdup(rec->notes);
                
                waypt_add(wpt_tmp);
        }
@@ -268,14 +285,18 @@ data_read(void)
                fatal(MYNAME ": Not a cotoGPS file.\n");
        }
        
-        if (pdb->version > 0) {
-             fatal(MYNAME ": This file is from an unsupported newer version of cotoGPS.  It may be supported in a newer version of GPSBabel.\n");
-       }
+        is_fatal((pdb->version > 0), 
+               MYNAME ": This file is from an unsupported newer version of cotoGPS.  It may be supported in a newer version of GPSBabel.\n");
        
-       if (pdb->type == MYTYPETRACK)
-               coto_track_read(pdb);
-       if (pdb->type == MYTYPEWPT)
-               coto_wpt_read(pdb);
+       switch(pdb->type)
+       {
+               case MYTYPETRACK:
+                       coto_track_read(pdb);
+                       break;
+               case MYTYPEWPT:
+                       coto_wpt_read(pdb);
+                       break;
+       }
 
        free_pdb(pdb);
 }
@@ -292,8 +313,8 @@ coto_prepare_wpt_write(struct pdb *opdb)
        
        strncpy(opdb->name, "cotoGPS MarkerDB", PDB_DBNAMELEN);
        
-       opdb->appinfo_len = APPINFO_PACKED_SIZE;
-       opdb->appinfo = calloc(APPINFO_PACKED_SIZE,1);
+       opdb->appinfo_len = APPINFO_SIZE;
+       opdb->appinfo = calloc(APPINFO_SIZE,1);
        
        ai = (struct appinfo *) opdb->appinfo;
        be_write16(&ai->renamedCategories, 31); // Don't ask me why...
@@ -311,11 +332,9 @@ coto_wpt_write(const waypoint *wpt)
        struct appinfo *ai = (struct appinfo *) opdb->appinfo;
        static int ct;
        struct pdb_record *opdb_rec;
-       static short_handle  mkshort_wr_handle;
        char *notes = NULL;
        char *shortname = NULL;
-       char *vdata;
-       int size = sizeof(*rec);
+       int size;
        ubyte cat = 0;
        int i;
        
@@ -323,44 +342,49 @@ coto_wpt_write(const waypoint *wpt)
        setshort_length(mkshort_wr_handle, MAX_MARKER_NAME_LENGTH);
        setshort_whitespace_ok(mkshort_wr_handle, 1);
        
-       if ((global_opts.synthesize_shortnames && wpt->description) || (!wpt->shortname))
+       if ((global_opts.synthesize_shortnames && wpt->description) || (wpt->shortname == NULL))
                shortname = mkshort_from_wpt(mkshort_wr_handle, wpt);
        else
                shortname = xstrdup(wpt->shortname);
        
-       if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname)))) {
-               if ((wpt->notes) && (strcmp(wpt->description, wpt->notes))) {
-                       size+=strlen(wpt->description)+strlen(wpt->notes)+9;
-                       notes = xcalloc(strlen(wpt->description)+strlen(wpt->notes)+9,1);
-                       sprintf(notes,"%s\nNotes:\n%s", wpt->description, wpt->notes);
+       if ((wpt->description) && ((strlen(wpt->description) > MAX_MARKER_NAME_LENGTH) || (strcmp(wpt->description, wpt->shortname))))
+       {
+               if ((wpt->notes) && (strcmp(wpt->description, wpt->notes) != 0)) 
+               {
+                       notes = xcalloc(strlen(wpt->description) + strlen(wpt->notes) + 9, 1);
+                       sprintf(notes, "%s\nNotes:\n%s", wpt->description, wpt->notes);
                } else {
-                       size+=strlen(wpt->description)+1;
                        notes = xstrdup(wpt->description);
                }
-       } else if (wpt->notes) {
-               size+=strlen(wpt->notes)+1;
+       } 
+       else if (wpt->notes != NULL)
+       {
                notes = xstrdup(wpt->notes);
        }
-       rec = xcalloc(size,1);
+       if (notes != NULL)
+               size += strlen(notes);
+       rec = xcalloc(size, 1);
+       
        pdb_write_double(&rec->lon, -2.0*M_PI*wpt->longitude/360.0);
        pdb_write_double(&rec->lat, 2.0*M_PI*wpt->latitude/360.0);
-       snprintf((char *) &rec->name, MAX_MARKER_NAME_LENGTH, "%s", shortname);
+       strncpy(rec->name, shortname, MAX_MARKER_NAME_LENGTH);
        
-       if (notes) {
-               vdata = (char *) rec + sizeof(*rec);
-               strcpy(vdata, notes);
+       if (notes)
+       {
+               strcpy(rec->notes, notes);
                xfree(notes);
        }
        
-       if (wpt->icon_descr) {
-               for(i=1;i<16;i++)
+       if (wpt->icon_descr)
+       {
+               for(i = 1; i < 16; i++)
                        if (!strncmp(wpt->icon_descr, ai->categories[i], 16)) {cat=i; break;}
                if (!cat) {
                        // We have a new one
                        if (ai->maxid<15) {
                                i = ++ai->maxid;
                                snprintf(ai->categories[i], 16, "%s", wpt->icon_descr);
-                               cat=ai->ids[i]=i;
+                               cat = ai->ids[i] = i;
                        } else {
                                // We're full!
                                warning(MYNAME ": Categories full. Category '%s' written as %s.\n", wpt->icon_descr, zerocat?zerocat:"Not Assigned");
@@ -370,18 +394,16 @@ coto_wpt_write(const waypoint *wpt)
        
        opdb_rec = new_Record (0, cat, ct++, size, (const ubyte *)rec);
        
-       if (opdb_rec == NULL) {
+       if (opdb_rec == NULL)
                fatal(MYNAME ": libpdb couldn't create record\n");
-       }
 
-       if (pdb_AppendRecord(opdb, opdb_rec)) {
+       if (pdb_AppendRecord(opdb, opdb_rec))
                fatal(MYNAME ": libpdb couldn't append record\n");
-       }
+
        xfree(shortname);
        xfree(rec);
        
        mkshort_del_handle(&mkshort_wr_handle);
-       
 }
 
 static void
@@ -392,9 +414,14 @@ data_write(void)
        }
        
        coto_prepare_wpt_write(opdb);
+       
        waypt_disp_all(coto_wpt_write);
+       /* 
+       if we want waypoints from all data, we should create a new filter for that
+       
        track_disp_all(NULL, NULL, coto_wpt_write);
        route_disp_all(NULL, NULL, coto_wpt_write);
+       */
        
        pdb_Write(opdb, fileno(file_out));
        
index de942e558f96ab29d82b34b6ef35ee36f7dc8239..1f04db89de8277ac45734d7ed4432501989e17f3 100644 (file)
@@ -1,21 +1,21 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <gpx
  version="1.0"
 creator="GPSBabel - http://www.gpsbabel.org"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://www.topografix.com/GPX/1/0"
 xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
-<time>2005-07-27T15:19:31Z</time>
+<time>1970-01-01T00:00:00Z</time>
 <bounds minlat="29.958683333" minlon ="-90.065533333" maxlat="48.570233333" maxlon="9.524850000" />
 <wpt lat="29.958683333" lon="-90.065533333">
   <name>GC2663</name>
-  <cmt>GC2663</cmt>
+  <cmt>New Orleans Bon Chance (Good Luck) Cache-Cam by CrotalusRex and Mimichan</cmt>
   <desc>New Orleans Bon Chance (Good Luck) Cache-Cam by CrotalusRex and Mimichan</desc>
   <sym>Geocache</sym>
 </wpt>
 <wpt lat="48.570233333" lon="9.524850000">
   <name>GCMK1V</name>
-  <cmt>GCMK1V</cmt>
+  <cmt>Randeck Maar Earthcache by Border</cmt>
   <desc>Randeck Maar Earthcache by Border</desc>
   <sym>Earthcache</sym>
 </wpt>
index d3101d128ae59eca0c29a350773eadb51e37c01b..dd3100b7c835f27705e2f69bbb1a11d11f0b0bd1 100755 (executable)
@@ -802,18 +802,20 @@ ${PNAME} -i gpx -f reference/dop-test.gpx -x discard,vdop=50 -o openoffice -F -
 compare ${TMPDIR}/dop-vdop.ref ${TMPDIR}/dop-vdop.fil
 
 #
-# cotoGPS test
+# cotoGPS tests
 #
-rm -f ${TMPDIR}/coto*
+rm -f ${TMPDIR}/coto*
 # Track reading
-# ${PNAME} -i coto -f reference/cototesttrack.pdb -o xcsv,style=reference/cototest.style -F ${TMPDIR}/cototrack.csv
-# compare reference/cototesttrack.csv ${TMPDIR}/cototrack.csv
-# Marker read/write
-# ${PNAME} -i coto -f reference/cototestmarker.pdb -o xcsv,style=reference/cototest.style -F ${TMPDIR}/cotomarker.csv
-# ${PNAME} -i gpx -f reference/cototestmarker.gpx -o xcsv,style=reference/cototest.style -F ${TMPDIR}/cotomarkergpx.csv
-# compare ${TMPDIR}/cotomarker.csv ${TMPDIR}/cotomarkergpx.csv
-# ${PNAME} -i gpx -f reference/cototestmarker.gpx -o coto -F ${TMPDIR}/cotomarker.pdb
-# compare reference/cototestmarker.pdb ${TMPDIR}/cotomarker.pdb
+${PNAME} -i coto -f reference/cototesttrack.pdb -o xcsv,style=reference/cototest.style -F ${TMPDIR}/cototrack.csv
+compare reference/cototesttrack.csv ${TMPDIR}/cototrack.csv
+# Marker read
+${PNAME} -i coto -f reference/cototestmarker.pdb -o gpx -F ${TMPDIR}/cotomarker.gpx
+compare reference/cototestmarker.gpx ${TMPDIR}/cotomarker.gpx
+# Marker write
+${PNAME} -i gpx -f reference/cototestmarker.gpx -o coto -F ${TMPDIR}/cotomarker.pdb
+# bincompare reference/cototestmarker.pdb ${TMPDIR}/cotomarker.pdb
+${PNAME} -i coto -f ${TMPDIR}/cotomarker.pdb -o gpx -F ${TMPDIR}/cotomarker.gpx
+compare reference/cototestmarker.gpx ${TMPDIR}/cotomarker.gpx
 
 #
 # Fugawi test cases
index cbd6cd1a265fc3c022c95a2e16843616848619ba..df3317261bd354b263eba1ea4d1443db8af8c84f 100644 (file)
@@ -433,14 +433,12 @@ vecs_t vec_list[] = {
                "Motorrad Routenplaner (Map&Guide) .bcr files",
                "bcr"
        },      
-#if 0
        {
                &coto_vecs,
                "coto",
                "cotoGPS for Palm/OS", 
                "pdb"
        },
-#endif
        {
                &ignr_vecs,
                "ignrando",